package com.delivery.controller;

import cn.hutool.core.lang.Snowflake;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.address_purification.model.v20191118.*;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.delivery.config.WxPayConfig;
import com.delivery.constant.DeliveryConstantEnum;
import com.delivery.entity.Order;
import com.delivery.entity.OrderCompensation;
import com.delivery.entity.User;
import com.delivery.form.SearchForm;
import com.delivery.interceptors.JWTInterceptor;
import com.delivery.mapper.OrderCompensationMapper;
import com.delivery.mapper.OrderMapper;
import com.delivery.mapper.UserMapper;
import com.delivery.result.ApiResult;
import com.delivery.utils.HttpUtils;
import com.delivery.utils.WxMiniPayUtils;
import com.delivery.utils.WxSignUtil;
import com.delivery.vo.*;
import com.google.gson.Gson;
import com.kuaidi100.sdk.api.BOrderOfficial;
import com.kuaidi100.sdk.api.ElecDetocr;
import com.kuaidi100.sdk.api.QueryTrack;
import com.kuaidi100.sdk.contant.ApiInfoConstant;
import com.kuaidi100.sdk.core.IBaseClient;
import com.kuaidi100.sdk.pojo.HttpResult;
import com.kuaidi100.sdk.request.*;
import com.kuaidi100.sdk.utils.SignUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import com.delivery.constant.DeliveryConstant;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author sixiao
 * @since 2023-04-10
 */
@RestController
@RequestMapping("/api/token")
@Api(tags = {"OrderController"},description = "所有接口均带token")
public class OrderController {

    @Autowired
    private DeliveryConstant deliveryConstant;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderCompensationMapper orderCompensationMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private String prefix = "delivery-order:";
    private String prefixCompensation = "delivery-order-compensation:";

    @Value("${constant.commission}")
    private String commission;
    
    @Autowired
    WxPayConfig autoWxPayConfig;

    @Resource(name = "taskExecutor")
    Executor executor;

    /**
     * 查询所有快递下单价格
     * @throws Exception
     * @RequestBody OrderPrice orderPrice
     */
    @PostMapping("/selectDownOrderPriceList")
    @ApiOperation(value = "查询所有快递公司下单价格",notes = "必传字段：kuaidicom快递公司，sendManPrintAddr发货地址，recManPrintAddr收货地址")
    public ApiResult selectOrderPriceList(@RequestBody DownOrderPriceList downOrderPriceList) {
        ArrayList<DownOrderPriceResultVo> downOrderPriceResultVos = new ArrayList<>();
        List<String> kuaidiCom = downOrderPriceList.getKuaidiCom();
        kuaidiCom.parallelStream().forEach(k->{
            try {
                DownOrderPrice downOrderPrice = new DownOrderPrice();
                BeanUtils.copyProperties(downOrderPriceList, downOrderPrice);
                downOrderPrice.setKuaidiCom(k);
                DownOrderPriceResultVo downOrderPriceResultVo = selectOrderPriceTo(downOrderPrice);
                //上浮价格
                if (downOrderPriceResultVo.getResult() == true) {
                    downOrderPriceResultVo.getData().setPrice(
                            downOrderPriceResultVo.getData().getPrice().multiply(new BigDecimal(commission )).setScale(1, BigDecimal.ROUND_HALF_UP)
                    );
                }
                downOrderPriceResultVos.add(downOrderPriceResultVo);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        //过滤无算力快递公司
        List<DownOrderPriceResultVo> filterList = downOrderPriceResultVos.stream()
                .filter(item -> item.getResult() == true)
                .sorted(Comparator.comparing(item -> item.getData().getPrice()))
                .collect(Collectors.toList());

        return ApiResult.ok(filterList);
    }

    //中转
    public DownOrderPriceResultVo selectOrderPriceTo(DownOrderPrice downOrderPrice) throws Exception {
        //打印请求对象
        PrintReq printReq = new PrintReq();
        //参数对象
        BOrderOfficialQueryPriceReq officialQueryPriceReq = new BOrderOfficialQueryPriceReq();

        //快递公司
        officialQueryPriceReq.setKuaidiCom(downOrderPrice.getKuaidiCom());
        officialQueryPriceReq.setWeight(downOrderPrice.getWeight());
        officialQueryPriceReq.setSendManPrintAddr(downOrderPrice.getSendManPrintAddr());
        officialQueryPriceReq.setRecManPrintAddr(downOrderPrice.getRecManPrintAddr());

        //时间戳
        String t = String.valueOf(System.currentTimeMillis());
        String param = new Gson().toJson(officialQueryPriceReq);
        printReq.setKey(deliveryConstant.key);
        printReq.setSign(SignUtils.printSign(param, t, deliveryConstant.key, deliveryConstant.secret));
        printReq.setT(t);
        printReq.setParam(param);
        printReq.setMethod(ApiInfoConstant.B_ORDER_OFFICIAL_PRICE_METHOD);

        IBaseClient bOrder = new BOrderOfficial();
        HttpResult execute = bOrder.execute(printReq);
        String body = execute.getBody();
        DownOrderPriceResultVo downOrderPriceResultVo = JSON.parseObject(body, DownOrderPriceResultVo.class);
//        //上浮价格
//        if (downOrderPriceResultVo.getResult() == true) {
//            downOrderPriceResultVo.getData().setPrice(
//                    downOrderPriceResultVo.getData().getPrice().multiply(new BigDecimal("1.15")).setScale(1, BigDecimal.ROUND_HALF_UP)
//            );
//        }
//
        return downOrderPriceResultVo;
    }


    /**
     * 下单
     *
     * 查价格
     * 扣钱
     * 存订单表
     */
    @PostMapping("/downOrder")
    @ApiOperation(value = "下单",notes = "必传字段：kuaidicom快递公司，收件人，收件人电话，收件人地址，发件人，发件人电话，发件人地址。重要字段：weight重量，valinsPay保价")
    public ApiResult downOrder(@RequestBody DownOrderVo downOrderVo) throws Exception {
        String userId = JWTInterceptor.userId;

        //查询用户下是否有待补缴订单
        List<Order> orders = orderMapper.selectList(
                new LambdaQueryWrapper<Order>()
                        .eq(Order::getUserId, userId)
                        .eq(Order::getPayStatus, DeliveryConstantEnum.StatusEnum.alreadyPay.getStatus()));

        if (orders.size() > 0) {
            List<OrderCompensation> orderCompensations = orderCompensationMapper.selectList(
                    new LambdaQueryWrapper<OrderCompensation>()
                            .in(OrderCompensation::getOrderId, orders.stream().map(Order::getId).collect(Collectors.toList()))
                            .eq(OrderCompensation::getPayStatus, DeliveryConstantEnum.StatusEnum.unpaid.getStatus())
            );

            if (orderCompensations.size() > 0) return ApiResult.fail("您有待补缴订单，请先补缴订单");

        }


        Order order = new Order();
        order.setUserId(Integer.valueOf(userId));

        //雪花算法生成订单号
        String code = new Snowflake().nextIdStr();
        order.setCode(code);
        order.setKuaidiCoding(downOrderVo.getKuaidiCom());

        order.setRecManName(downOrderVo.getRecManName());
        order.setRecManMobile(downOrderVo.getRecManMobile());
        order.setRecManPrintAddr(downOrderVo.getRecManPrintAddr());

        order.setSendManName(downOrderVo.getSendManName());
        order.setSendManMobile(downOrderVo.getSendManMobile());
        order.setSendManPrintAddr(downOrderVo.getSendManPrintAddr());

        order.setCargo(downOrderVo.getCargo());
        order.setWeight(downOrderVo.getWeight());
        order.setValinsPay(downOrderVo.getValinsPay());
        order.setRemark(downOrderVo.getRemark());
        order.setOrderTime(new Date());

        //查询订单价格
        DownOrderPrice downOrderPrice = new DownOrderPrice();
        BeanUtils.copyProperties(downOrderVo,downOrderPrice);
        DownOrderPriceResultVo downOrderPriceResultVo = selectOrderPriceTo(downOrderPrice);

        //设置快递100预扣价格
        order.setOrderAmountWithhold(downOrderPriceResultVo.getData().getPrice());
        //上浮订单价格
        order.setOrderAmount(downOrderPriceResultVo.getData().getPrice().multiply(new BigDecimal(commission )).setScale(1, BigDecimal.ROUND_HALF_UP));

        //Java对象转换成JSON字符串
        String orderStr = JSONObject.toJSONString(order);

        //插入数据库待支付订单
      //  orderMapper.insert(order);
        User user = userMapper.selectById(userId);

        Integer amount = (order.getOrderAmount().multiply(new BigDecimal("100")) ).intValue();
        //提交订单
        String response= WxMiniPayUtils.creatOrderJSAPI( user.getOpenId() , code, amount ,DeliveryConstantEnum.payTypeEnum.deliveryOrder.getTyep(),"寄件支付" );
        JSONObject jsonObject = JSONObject.parseObject(response);

        if (jsonObject.containsKey("prepay_id")){
            //已提交腾讯待支付订单
            String prepay_id = jsonObject.get("prepay_id").toString();
            String WxSign = WxSignUtil.getWxAppPayTuneUp(prepay_id);
            //待支付订单存入redis 60, TimeUnit.MINUTES
             stringRedisTemplate.opsForValue().set(prefix + code, orderStr ,60, TimeUnit.MINUTES);
            JSONObject res = JSONObject.parseObject(WxSign);

            return ApiResult.ok(res);
        }else {
            throw new RuntimeException ("订单提交失败！");
        }

    }


    @GetMapping("/compensationView")
    @ApiOperation(value = "运费补缴页面所需接口",notes = "传订单 id")
    public ApiResult compensationView(@RequestParam Integer id)  {
        Order order = orderMapper.selectById(id);
        OrderCompensation orderCompensation = orderCompensationMapper.selectOne(
                new LambdaQueryWrapper<OrderCompensation>()
                        .eq(OrderCompensation::getOrderId, order.getId())
        );
        BigDecimal subtract = orderCompensation.getOrderAmount().subtract(order.getOrderAmount());

        CompensationViewVo compensationViewVo = new CompensationViewVo();
        compensationViewVo.setKuaidinum(order.getKuaidinum());
        compensationViewVo.setCompensationAmount(subtract);
        compensationViewVo.setCargo(order.getCargo());
        compensationViewVo.setPayWeight(order.getWeight());
        compensationViewVo.setFreightWeight(orderCompensation.getWeight());
        compensationViewVo.setWeight( new BigDecimal(orderCompensation.getWeight()).setScale( 0, BigDecimal.ROUND_UP ).toString() );

      return ApiResult.ok(compensationViewVo);
    }
    
    @GetMapping("/compensationOrder")
    @ApiOperation(value = "运费补缴",notes = "传订单 id")
    public ApiResult compensationOrder(@RequestParam Integer id) throws Exception {
        String userId = JWTInterceptor.userId;
        User user = userMapper.selectById(userId);

        Order order = orderMapper.selectById(id);
        OrderCompensation orderCompensation = orderCompensationMapper.selectOne(
                new LambdaQueryWrapper<OrderCompensation>()
                        .eq(OrderCompensation::getOrderId, order.getId())
        );
        BigDecimal subtract = orderCompensation.getOrderAmount().subtract(order.getOrderAmount());
        Integer amount = (subtract.multiply(new BigDecimal("100")) ).intValue();

        String code = new Snowflake().nextIdStr();
        //提交订单
        String response= WxMiniPayUtils.creatOrderJSAPI(user.getOpenId(), code , amount ,DeliveryConstantEnum.payTypeEnum.compensationOrder.getTyep(),"寄件超重补缴" );
        JSONObject jsonObject = JSONObject.parseObject(response);

        if (jsonObject.containsKey("prepay_id")){
            //已提交腾讯待支付订单
            String prepay_id = jsonObject.get("prepay_id").toString();
            String WxSign = WxSignUtil.getWxAppPayTuneUp(prepay_id);
            //待支付订单存入redis 60, TimeUnit.MINUTES
            stringRedisTemplate.opsForValue().set(prefixCompensation + code , JSONObject.toJSONString(orderCompensation) ,15, TimeUnit.MINUTES);
            JSONObject res = JSONObject.parseObject(WxSign);

            return ApiResult.ok(res);
        }else {
            throw new RuntimeException ("订单提交失败！");
        }

    }


    /**
     * 取消订单
     *
     * 退单
     * 退钱
     * 改订单表
     */
    @PostMapping("/cancelOrder")
    @ApiOperation(value = "取消订单",notes = "必传字段：taskId任务ID，orderId订单id")
    @Transactional
    public ApiResult testBorderOfficialCancel(@RequestBody BOrderCancelReq bOrderCancelReq) throws Exception {
        PrintReq printReq = new PrintReq();
        String t = String.valueOf(System.currentTimeMillis());
        String param = new Gson().toJson(bOrderCancelReq);

        printReq.setKey(deliveryConstant.key);
        printReq.setSign(SignUtils.printSign(param,t,deliveryConstant.key,deliveryConstant.secret));
        printReq.setT(t);
        printReq.setParam(param);
        printReq.setMethod(ApiInfoConstant.B_ORDER_OFFICIAL_CANCEL_METHOD);

        IBaseClient bOrder = new BOrderOfficial();
        HttpResult execute = bOrder.execute(printReq);
        //{"data":{},"message":"取消成功","result":true,"returnCode":"200"}
        String body = execute.getBody();
        DancelOrderResultVo dancelOrderResultVo = JSON.parseObject(body, DancelOrderResultVo.class);

        if (dancelOrderResultVo.getResult()){
            // 异步退钱
            CompletableFuture.runAsync(() -> {
                Order order = orderMapper.selectOne(
                        new LambdaQueryWrapper<Order>()
                                .eq(Order::getTaskid, bOrderCancelReq.getTaskId())
                );
            JSONObject domesticRefundsJSON = new JSONObject();
            domesticRefundsJSON.put("transaction_id", order.getTransactionId());
            //雪花算法生成退款订单号
            String outRefundNo = new Snowflake().nextIdStr();
            domesticRefundsJSON.put("out_refund_no", outRefundNo);
            domesticRefundsJSON.put("reason","取消寄件订单");
            JSONObject amount = new JSONObject();
            amount.put("refund", (order.getOrderAmount().multiply(new BigDecimal("100"))).intValue()  );
            amount.put("total",  (order.getOrderAmount().multiply(new BigDecimal("100"))).intValue());
            amount.put("currency","CNY");
            domesticRefundsJSON.put("amount",amount);
            domesticRefundsJSON.put("notify_url", autoWxPayConfig.getRefundsNotifyDomain() );
            String parm = domesticRefundsJSON.toJSONString();
            String domesticRefundsBody = null;
                try {
                    domesticRefundsBody = WxMiniPayUtils.v3Post("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds",parm);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
          //  JSONObject domesticRefundsBodyJSON = JSON.parseObject(domesticRefundsBody);

        }, executor);


            return ApiResult.ok(dancelOrderResultVo);
        }else {
            return ApiResult.fail(dancelOrderResultVo);
        }

    }

    //查询物流
    @PostMapping("/logisticsQuery")
    @ApiOperation(value = "查询物流",notes = "必传字段：num快递单号，com快递公司")
    public ApiResult testQueryTrack(@RequestBody QueryTrackParam queryTrackParam) throws Exception{
        QueryTrackReq queryTrackReq = new QueryTrackReq();
        String param = new Gson().toJson(queryTrackParam);
        queryTrackReq.setParam(param);
        queryTrackReq.setCustomer(deliveryConstant.customer);
        queryTrackReq.setSign(SignUtils.querySign(param ,deliveryConstant.key,deliveryConstant.customer));
        IBaseClient baseClient = new QueryTrack();
        HttpResult execute = baseClient.execute(queryTrackReq);
        String body = execute.getBody();
        logisticsQueryResultVo logisticsQueryResultVo = JSON.parseObject(body, logisticsQueryResultVo.class);
        return ApiResult.ok(logisticsQueryResultVo);
    }


    /**
     * 查询用户所有订单
     */
    @PostMapping("/selectOrderByUserId")
    @ApiOperation(value = "分页查询用户所有订单 ",notes = "")
    public ApiResult selectOrderByUserId(@RequestBody SearchForm searchForm){
          String userId = JWTInterceptor.userId;
          Page<OrderListVo> page = new Page<>(searchForm.getCurrent(),searchForm.getPageSize());
          Page<OrderListVo> orderListVoPage = orderMapper.selectOrderByUserId(page, userId, searchForm);

//        Page<Order> orderPage = new Page<>(searchForm.getCurrent(),searchForm.getPageSize());
//        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(Order::getUserId,userId)
//               .and(searchForm.getKeywords() != null, i->{
//                   i.like(Order::getRecManName , searchForm.getKeywords())
//                    .or().like(Order::getSendManName , searchForm.getKeywords())
//                    .or().eq(Order::getKuaidinum , searchForm.getKeywords())
//                    .or().eq(Order::getRecManMobile, searchForm.getKeywords())
//                    .or().eq(Order::getSendManMobile, searchForm.getKeywords());})
//               .eq(searchForm.getOrderStatus() != null, Order::getOrderStatus,searchForm.getOrderStatus())
//               .eq(searchForm.getDeliveryStatus() != null, Order::getOrderStatus,searchForm.getDeliveryStatus())
//               .orderBy(true,false,Order::getOrderTime);
//
//        Page<Order> page = orderService.page(orderPage, wrapper);
//
//        if(page.getRecords().size() > 0){
//            List<Integer> ids = page.getRecords().stream().map(item -> item.getId()).collect(Collectors.toList());
//            List<OrderCompensation> orderCompensations = orderCompensationMapper.selectList(
//                    new LambdaQueryWrapper<OrderCompensation>()
//                            .in(OrderCompensation::getOrderId, ids)
//                            .eq(OrderCompensation::getPayStatus, DeliveryConstantEnum.StatusEnum.unpaid.getStatus())
//            );
//            List<OrderListVo> collect;
//
//            if(orderCompensations.size() > 0){
//                collect = page.getRecords().stream().map(order -> {
//                    OrderListVo orderPayVo = new OrderListVo();
//                    BeanUtils.copyProperties(order, orderPayVo);
//                    orderCompensations.stream().forEach(orderCompensation -> {
//                        if (order.getId() == orderCompensation.getOrderId()) orderPayVo.setIsCompensation(true);
//                    });
//                    return orderPayVo;
//                }).collect(Collectors.toList());
//                Page<OrderListVo> UserOrderList = new Page<>();
//                UserOrderList.setCurrent(page.getCurrent());
//                UserOrderList.setPages(page.getPages());
//                UserOrderList.setSize(page.getSize());
//                UserOrderList.setTotal(page.getTotal());
//                UserOrderList.setRecords(collect);
//                return ApiResult.ok( UserOrderList );
//            }
//        }

        return ApiResult.ok( orderListVoPage );
    }

    @GetMapping("/selectOrderInfo")
    @ApiOperation(value = "根据订单taskId查询详情 ",notes = "")
    public ApiResult selectOrderInfo(@RequestParam String taskId) throws Exception {

        PrintReq printReq = new PrintReq();
        BOrderOfficialQueryDetailReq officialQueryPriceReq = new BOrderOfficialQueryDetailReq();

        officialQueryPriceReq.setTaskId(taskId);

        String t = String.valueOf(System.currentTimeMillis());
        String param = new Gson().toJson(officialQueryPriceReq);

        printReq.setKey(deliveryConstant.key);
        printReq.setSign(SignUtils.printSign(param,t,deliveryConstant.key,deliveryConstant.secret));
        printReq.setT(t);
        printReq.setParam(param);
        printReq.setMethod(ApiInfoConstant.DETAIL);

        IBaseClient bOrder = new BOrderOfficial();
        HttpResult execute = bOrder.execute(printReq);
        String body = execute.getBody();
        JSONObject jsonObject = JSONObject.parseObject(body);
        //data里面得数据
        JSONObject jsonObjectData = JSONObject.parseObject(jsonObject.get("data").toString()) ;

        Order orderId = orderMapper.selectOne(
                new LambdaQueryWrapper<Order>()
                        .eq(Order::getKuaidi100Id, jsonObjectData.get("orderId").toString())
        );
        OrderCompensation orderCompensation = orderCompensationMapper.selectOne(
                new LambdaQueryWrapper<OrderCompensation>()
                        .eq(OrderCompensation::getOrderId, orderId.getId())
                        .eq(OrderCompensation::getPayStatus, DeliveryConstantEnum.StatusEnum.unpaid.getStatus())
        );
        //标记待付款订单
        if (orderCompensation != null) jsonObjectData.put("compensationPayStatus",orderCompensation.getPayStatus());

        //赋值付款金额
        if(orderId != null) jsonObjectData.put("orderAmount",orderId.getOrderAmount());

        //赋值订单id
        if(orderId != null) jsonObjectData.put("id",orderId.getId());

        Object freight = jsonObjectData.get("freight");
        if(freight != null){
            //更改最终价格
            jsonObjectData.put("freight", new BigDecimal(freight.toString())
                    .multiply(new BigDecimal("1.15")).setScale(1, BigDecimal.ROUND_HALF_UP) );
        }

        Object lastWeight = jsonObjectData.get("lastWeight");
        if(lastWeight != null){
            //更改计费价格
            jsonObjectData.put("lastWeight",new BigDecimal(lastWeight.toString()).setScale( 0, BigDecimal.ROUND_UP ).toString() );
        }

        jsonObject.put("data",jsonObjectData);
        //返回详情
        return ApiResult.ok(jsonObject);
    }


    //地址三级联动
    @PostMapping("/address3")
    @ApiOperation(value = "地址联动",notes = "需要传参 keyword ")
    public ApiResult address3(@RequestBody Map<String,String> keywords) throws Exception{
        HashMap<String, String> header = new HashMap<>();  //空请求头
        Map<String, String> map = new HashMap();
        map.put("keywords",keywords.get("keywords"));
        map.put("subdistrict","1");
        map.put("key",deliveryConstant.dKey);
        //1、根据code换取accessToken
        //工具类发送请求 主机地址，路径，请求方式，请求头，请求体，参数hashmap
        HttpResponse response = HttpUtils.doGet("https://restapi.amap.com", "/v3/config/district", "get", header, map);
        //2、处理  获取响应状态行，获取状态码
        if(response.getStatusLine().getStatusCode()==200){
            String json = EntityUtils.toString(response.getEntity());
            Address3ResultVo address3ResultVo = JSON.parseObject(json, Address3ResultVo.class);

            return ApiResult.ok(address3ResultVo);
        }
        return null;
    }


    /**
     *快递面单OCR识别
     */
    @PostMapping("/OCR")
    @ApiOperation(value = "图片识别地址 电话 姓名",notes = "上传一张图片 name属性为:img")
    public ApiResult OCR(MultipartFile img) throws Exception {
        OrcParam orcParam = new OrcParam();
        InputStream in = img.getInputStream();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        //建一个空的字节数组
        byte[] result = null;
        byte[] buf = new byte[1024];
        //用来定义一个准备接收图片总长度的局部变量
        int len;
        //将流的内容读取到buf内存中
        while ((len = in.read(buf)) > 0) {
            //将buf内存中的内容从0开始到总长度输出出去
            out.write(buf, 0, len);
        }
        //将out中的流内容拷贝到一开始定义的字节数组中
        result = out.toByteArray();
        //通过util包中的Base64类对字节数组进行base64编码
        String base64 = Base64.getEncoder().encodeToString(result);
//        orcParam.setImage("http://124.222.190.68/1.jpg");
        orcParam.setImage(base64);
        String param = new Gson().toJson(orcParam);

        PrintReq printReq = new PrintReq();
        printReq.setKey(deliveryConstant.key);
        printReq.setParam(param);

        IBaseClient orc = new ElecDetocr();
        HttpResult execute = orc.execute(printReq);
        String body = execute.getBody();
        System.out.println(body);
        OCRResultVo ocrResultVo = JSON.parseObject(body, OCRResultVo.class);
        return ApiResult.ok(ocrResultVo);
    }

    @PostMapping("/OCR2")
    @ApiOperation(value = "图片识别地址 电话 姓名",notes = "上传一张图片 name属性为:img")
    public ApiResult OCR2(@RequestBody Map<String,String> map) throws Exception {
        OrcParam orcParam = new OrcParam();
        String text = map.get("text").toString();
        byte[] bytes = text.getBytes();
        //通过util包中的Base64类对字节数组进行base64编码
        String base64 = Base64.getEncoder().encodeToString(bytes);
//        orcParam.setImage("http://124.222.190.68/1.jpg");
        orcParam.setImage(base64);
        String param = new Gson().toJson(orcParam);

        PrintReq printReq = new PrintReq();
        printReq.setKey(deliveryConstant.key);
        printReq.setParam(param);

        IBaseClient orc = new ElecDetocr();
        HttpResult execute = orc.execute(printReq);
        String body = execute.getBody();
        System.out.println(body);
        OCRResultVo ocrResultVo = JSON.parseObject(body, OCRResultVo.class);
        return ApiResult.ok(ocrResultVo);
    }


    //识别地址 电话 姓名
    @PostMapping("/stringOCR")
    @ApiOperation(value = "文本识别地址 电话 姓名",notes = "必传字段：text文本内容")
    public ApiResult stringOCR(@RequestBody Map<String,String> map) throws  ExecutionException, InterruptedException {
        if( map.get("text").contains("详细地址:") )  {
            map.put("text",map.get("text").replaceAll("详细地址:",""));
        }
        String text = map.get("text");
        Map<String, Object> stringHashMap = new HashMap<>();
        DefaultProfile profile = DefaultProfile.getProfile(
                "cn-hangzhou",
                deliveryConstant.accessKey,
                deliveryConstant.accessSecret);
        IAcsClient client = new DefaultAcsClient(profile);


        CompletableFuture<Void> completableFuture= CompletableFuture.runAsync(() -> {
            ExtractPhoneRequest requestPhone = new ExtractPhoneRequest();
            requestPhone.setAppKey("68ezksnxct1w");
            requestPhone.setText(text);
            ExtractPhoneResponse responsePhone = null;
            try {
                responsePhone = client.getAcsResponse(requestPhone);
            } catch (ClientException e) {
                e.printStackTrace();
            }
            String dataPhone = responsePhone.getData();

            StringOCRResultVo stringOCRResultVo=JSON.parseObject(dataPhone, StringOCRResultVo.class);
            stringHashMap.put("phone",stringOCRResultVo.getPhone_extract().get(0).getWord());

        }, executor);

        CompletableFuture<Void> completableFuture2= CompletableFuture.runAsync(() -> {
            ExtractAddressRequest requestAddress = new ExtractAddressRequest();
            requestAddress.setAppKey("68ezksnxct1w");
            requestAddress.setText(text);
            ExtractAddressResponse response = null;
            try {
                response = client.getAcsResponse(requestAddress);
            } catch (ClientException e) {
                e.printStackTrace();
            }
            String dataAddress = response.getData();
            System.out.println("dataAddress = " + dataAddress);
            StringOCRResultVo stringOCRResultVo = JSON.parseObject(dataAddress, StringOCRResultVo.class);
            String word = stringOCRResultVo.getLocation_extract().get(0).getWord();
            String word2 = word.substring(word.indexOf("市") + 1);
            String word3 = word2.substring(word2.indexOf("县") + 1);
            String word4 = word3.substring(word3.indexOf("区") + 1);
            stringHashMap.put("address",word4);

        }, executor);

        CompletableFuture<Void> completableFuture3= CompletableFuture.runAsync(() -> {
            ExtractNameRequest requestName = new ExtractNameRequest();
            requestName.setAppKey("68ezksnxct1w");
            requestName.setText(text);
            ExtractNameResponse responseName = null;
            try {
                responseName = client.getAcsResponse(requestName);
            } catch (ClientException e) {
                e.printStackTrace();
            }
            String dataName = responseName.getData();
            StringOCRResultVo stringOCRResultVo= JSON.parseObject(dataName, StringOCRResultVo.class);
            stringHashMap.put("name",stringOCRResultVo.getPerson_extract().get(0).getWord());
        }, executor);

        CompletableFuture<Void> completableFuture4= CompletableFuture.runAsync(() -> {
            IAcsClient client2 = new DefaultAcsClient(profile);
            GetAddressDivisionCodeRequest request = new GetAddressDivisionCodeRequest();
            request.setAppKey("68ezksnxct1w");
            request.setServiceCode("addrp");
            request.setText(text);
            GetAddressDivisionCodeResponse response = null;
            try {
                response = client2.getAcsResponse(request);
            } catch (ClientException e) {
                e.printStackTrace();
            }
            String data = response.getData();
            AddressAnalysisResultVo addressAnalysisResultVo = JSON.parseObject(data, AddressAnalysisResultVo.class);
            String[] split = addressAnalysisResultVo.getDivision_info().getDivision_name().split(";");
            stringHashMap.put("addressAnalysis",split);
            System.out.println(data);
        }, executor);

        CompletableFuture<Void> allOf = CompletableFuture.allOf(completableFuture, completableFuture2, completableFuture3,completableFuture4);
        allOf.get();//等待所有结果完成,继续往下
//        Object o = stringHashMap.get("addressAnalysis");
//        String[] addressAnalyses = (String[]) stringHashMap.get("addressAnalysis");
        stringHashMap.put("address",stringHashMap.get("address"));
        return ApiResult.ok(stringHashMap);
    }




}
